import java.util.Arrays;
import java.util.Scanner;

public class Main1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        // 读取输入
        int N = sc.nextInt();  // 天数
        int M = sc.nextInt();  // 股票支数
        double K = sc.nextDouble();  // 初始资金

        double[][] price = new double[N+1][M];
        // 约定 price[d][i] 表示第 d 天(1<=d<=N) 的 i 号股票价格(0<=i<M)
        // 但实际数组下标从1开始存第1天到N天，以方便阅读
        for (int d = 1; d <= N; d++) {
            for (int i = 0; i < M; i++) {
                price[d][i] = sc.nextDouble();
            }
        }

        // -------------------------------
        // 定义dp数组
        // dpCash[d] = 第 d 天结束时持有现金时的最大金额
        // dpStock[i][d] = 第 d 天结束时持有股票 i 时最多可持有的股数
        // 由于N最多为20，我们可以直接开N+1大小
        double[] dpCash = new double[N+1];
        double[][] dpStock = new double[M][N+1];

        // 记录决策来源，用于回溯输出交易操作
        // prevCashFrom[d] = -1 表示来自dpCash[d-1]，或表示来自卖出的是哪只股票
        // 如果是卖出股票 j ，则 prevCashFrom[d] = j (0 <= j < M)
        int[] prevCashFrom = new int[N+1];
        Arrays.fill(prevCashFrom, -1);

        // prevStockFrom[i][d] 记录的是 dpStock[i][d] 的最大值究竟来自三种可能中的哪一种
        // -1 表示“昨天已经持有i，不动”
        // -2 表示“昨天是现金，今天买入 i”
        // >= 0 表示“昨天是股票 j (j != i)，先卖 j 再买 i”
        int[][] prevStockFrom = new int[M][N+1];
        for(int i=0; i<M; i++){
            Arrays.fill(prevStockFrom[i], -1);
        }

        // 初始化：第0天手里只有现金K，没股票
        dpCash[0] = K;
        for (int i = 0; i < M; i++) {
            dpStock[i][0] = 0.0;
        }

        // -------------------------------
        // 开始DP
        for (int d = 1; d <= N; d++) {
            // 先计算 sellValue[d] = max over j of (dpStock[j][d-1] * price[d][j])
            double sellValue = 0.0;
            int bestStockToSell = -1;  // 记录哪只股票卖了可得到最大现金
            for (int j = 0; j < M; j++) {
                double possibleCash = dpStock[j][d-1] * price[d][j];
                if (possibleCash > sellValue) {
                    sellValue = possibleCash;
                    bestStockToSell = j;
                }
            }

            // 计算 dpCash[d]
            // 1) 不变：dpCash[d-1]
            // 2) 卖出所得：sellValue
            if (dpCash[d-1] >= sellValue) {
                dpCash[d] = dpCash[d-1];
                prevCashFrom[d] = -1;  // 表示保持原状（没有卖出任何股票）
            } else {
                dpCash[d] = sellValue;
                prevCashFrom[d] = bestStockToSell; // 表示卖出 bestStockToSell
            }

            // 计算 dpStock[i][d] 对每个 i
            for (int i = 0; i < M; i++) {
                // 1) 继续持有同样的股票 i
                double keepOld = dpStock[i][d-1];
                // 2) 从现金买 i
                double buyFromCash = dpCash[d-1] / price[d][i];
                // 3) 从“先卖再买”
                double buyFromStock = sellValue / price[d][i];

                // 找到这三种可能的最大值
                double maxVal = keepOld;
                int fromFlag = -1;   // -1 表示“昨天就是i，不动”

                if (buyFromCash > maxVal) {
                    maxVal = buyFromCash;
                    fromFlag = -2;   // -2 表示“昨天是现金买 i”
                }
                if (buyFromStock > maxVal) {
                    maxVal = buyFromStock;
                    fromFlag = bestStockToSell; // >= 0，表示先卖 bestStockToSell 后买 i
                }

                dpStock[i][d] = maxVal;
                prevStockFrom[i][d] = fromFlag;
            }
        }

        // -------------------------------
        // 最终答案：dpCash[N]
        double answer = dpCash[N];

        // 我们还需要回溯所有天的操作 (共N天)，然后逆序输出或先存下来再正序输出
        // 为了方便，先建一个数组 operations[d] = [X, Y]，表示第 d 天的操作
        // 若X=-1,Y=-1则无操作；若X!=-1且Y=-1则只卖出X；若X=-1且Y!=-1则只买入Y；若X!=-1且Y!=-1则卖X买Y。
        int[][] operations = new int[N+1][2];
        for (int d = 0; d <= N; d++) {
            operations[d][0] = -1;
            operations[d][1] = -1;
        }

        // 我们需要知道“最后一天”结束时是在现金状态 dpCash[N]。
        // 然后往回推，每天是如何到达那个状态或者到达dpStock[i][d]的。
        // 回溯指针从 d = N 开始
        int curState = 0; // 0 表示当前是现金状态, 1表示当前是某只股票状态
        int curStock = -1; // 若 curState=1，则表示是哪只股票

        // 从后往前
        for (int d = N; d >= 1; d--) {
            if (curState == 0) {
                // 说明第 d 天结束时，我们选择了dpCash[d]。
                // 看 prevCashFrom[d] 是不是卖出来的？
                int from = prevCashFrom[d];
                if (from == -1) {
                    // 表示“保持原状”：dpCash[d] = dpCash[d-1]
                    // 则当天无操作
                    // 接下来 d-1 天结束时仍然是现金
                    curState = 0;
                } else {
                    // from >= 0，表示来自卖出股票 from
                    // 那么当天一定是“卖出 from”，没有买入
                    operations[d][0] = from; // 卖出
                    operations[d][1] = -1;   // 不买
                    // 卖出股票后当日结束是现金，所以 d-1 天结束时必然是“持有那只股票 from”。
                    curState = 1;
                    curStock = from;
                }
            } else {
                // curState=1，表示第 d 天结束时手上是某只股票 curStock
                // 那么我们看 prevStockFrom[curStock][d] 的来源
                int fromFlag = prevStockFrom[curStock][d];
                if (fromFlag == -1) {
                    // 昨天就是持有curStock不动
                    // 那么 d 天无操作
                    // d-1 天结束时也是持有 curStock
                    curState = 1;
                    // curStock 不变
                } else if (fromFlag == -2) {
                    // 表示第 d 天是由“昨天现金”买入的
                    // 那么 d 天一定发生了“买入 curStock”，且没有卖出
                    operations[d][0] = -1;
                    operations[d][1] = curStock;
                    // 所以 d-1 天结束时应当是现金
                    curState = 0;
                } else {
                    // fromFlag >= 0, 表示先卖出股票 fromFlag，再买入 curStock
                    int stockSold = fromFlag;
                    operations[d][0] = stockSold;
                    operations[d][1] = curStock;
                    // 所以 d-1 天结束时应是持有 stockSold
                    curState = 1;
                    curStock = stockSold;
                }
            }
        }

        // 由于我们是从后往前回溯的，operations[d] 已经正确，但最终需要从前往后输出。
        // 答案在 answer = dpCash[N].
        System.out.printf("%.4f\n", answer);

        // 输出每天的操作
        // 第 1 天到第 N 天
        for (int d = 1; d <= N; d++) {
            System.out.println(operations[d][0] + " " + operations[d][1]);
        }
    }
}
